package com.sicheng.蓝桥.练习题.差分;

import java.io.*;

/**
 * @author zsc
 * @version 1.0
 * @date 2022/5/18 15:56
 */
public class 二维差分 {
    /**
     * 输入一个 n 行 m 列的整数矩阵，再输入 q 个操作，
     * 每个操作包含五个整数 x1,y1,x2,y2,c，
     * 其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。
     * 每个操作都要将选中的子矩阵中的每个元素的值加上 c。
     * 请你将进行完所有操作后的矩阵输出。
     * 输入格式
     * 第一行包含整数 n,m,q。
     * <p>
     * 接下来 n 行，每行包含 m 个整数，表示整数矩阵。
     * <p>
     * 接下来 q 行，每行包含 5 个整数 x1,y1,x2,y2,c，表示一个操作。
     * <p>
     * 输出格式
     * 共 n 行，每行 m 个整数，表示所有操作进行完毕后的最终矩阵。
     * <p>
     * 数据范围
     * 1≤n,m≤1000,
     * 1≤q≤100000,
     * 1≤x1≤x2≤n,
     * 1≤y1≤y2≤m,
     * −1000≤c≤1000,
     * −1000≤矩阵内元素的值≤1000
     * 输入样例：
     * 3 4 3
     * 1 2 2 1
     * 3 2 2 1
     * 1 1 1 1
     * 1 1 2 2 1
     * 1 3 2 3 2
     * 3 1 3 4 1
     * 输出样例：
     * 2 3 4 1
     * 4 3 4 1
     * 2 2 2 2
     */
    public static void main(String[] args) throws IOException {
        //普遍Scanner会超时，所以使用BufferedReader
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
        String[] str1 = reader.readLine().split(" ");

        int n = Integer.parseInt(str1[0]);
        int m = Integer.parseInt(str1[1]);
        int q = Integer.parseInt(str1[2]);
        int[][] a = new int[n + 2][m + 2];
        int[][] b = new int[n + 2][m + 2];

        // 读入原数组
        for (int i = 1; i <= n; i++) {
            String[] str2 = reader.readLine().split(" ");
            for (int j = 1; j <= m; j++) {
                a[i][j] = Integer.parseInt(str2[j - 1]);
                // 初始化差分数组
                insert(b, i, j, i, j, a[i][j]);
            }
        }


        while (q-- > 0) {
            String[] str3 = reader.readLine().split(" ");
            int x1 = Integer.parseInt(str3[0]);
            int y1 = Integer.parseInt(str3[1]);
            int x2 = Integer.parseInt(str3[2]);
            int y2 = Integer.parseInt(str3[3]);
            int k = Integer.parseInt(str3[4]);
            insert(b, x1, y1, x2, y2, k);
        }

        prefixSum(n, m, b);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                writer.write(b[i][j] + " ");
            }
            writer.newLine();
        }
        //所有write下的内容，会先存在writers中，当启用flush以后，
        //会输出存在其中的内容。如果没有调用flush，则不会将writer中的内容进行输出。
        writer.flush();
        reader.close();
        writer.close();
    }

    private static void prefixSum(int n, int m, int[][] b) {
        // 求b数组的前缀和
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1];
            }
        }
    }

    // 插入操作函数
    private static void insert(int[][] b, int x1, int y1, int x2, int y2, int k) {
        b[x1][y1] += k;
        b[x2 + 1][y1] -= k;
        b[x1][y2 + 1] -= k;
        b[x2 + 1][y2 + 1] += k;
    }

    //matrix[i][j]表示二维前缀和
    //公式： 求某个子区间的前缀和  左上角(row1,col1) 右下角(row2,col2)
    //matrix[row2][col2] + matrix[row1 - 1][col1 - 1] - matrix[row1 - 1][col2] - matrix[row2][col1 - 1];


}
